// Sample TypeScript file for testing
import { EventEmitter } from 'events';
import axios, { AxiosResponse } from 'axios';
import * as path from 'path';
import { UserData, ApiResponse } from './types';

// Interface definition
interface Config {
    apiUrl: string;
    timeout?: number;
    retries: number;
}

// Type alias
type Status = 'pending' | 'completed' | 'failed';

// Enum
enum Priority {
    LOW = 1,
    MEDIUM = 2,
    HIGH = 3
}

// Class with inheritance and generics
class ApiClient<T = any> extends EventEmitter {
    private config: Config;
    private cache: Map<string, T> = new Map();

    constructor(config: Config) {
        super();
        this.config = config;
    }

    async fetchData(endpoint: string): Promise<ApiResponse<T>> {
        try {
            const response: AxiosResponse<T> = await axios.get(
                `${this.config.apiUrl}${endpoint}`,
                { timeout: this.config.timeout || 5000 }
            );
            
            this.cache.set(endpoint, response.data);
            this.emit('data', response.data);
            
            return {
                data: response.data,
                status: 'completed' as Status,
                timestamp: Date.now()
            };
        } catch (error) {
            this.emit('error', error);
            throw error;
        }
    }

    // Async generator
    async* batchProcess(items: string[]): AsyncGenerator<T, void, unknown> {
        for (const item of items) {
            const result = await this.fetchData(item);
            yield result.data;
        }
    }

    // Method with dynamic calls
    executeAction(action: string, params: any = {}): any {
        const method = this[action as keyof this];
        if (typeof method === 'function') {
            return (method as Function).call(this, params);
        }
    }
}

// Function with async/await
async function processUser(userId: string): Promise<UserData> {
    const client = new ApiClient<UserData>({
        apiUrl: 'https://api.example.com',
        retries: 3
    });

    try {
        const response = await client.fetchData(`/users/${userId}`);
        return response.data;
    } catch (error) {
        console.error('Failed to process user:', error);
        throw error;
    }
}

// Arrow function with Promise
const validateInput = (input: string): Promise<boolean> => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (input.length > 0) {
                resolve(true);
            } else {
                reject(new Error('Invalid input'));
            }
        }, 100);
    });
};

// Promise combinators
async function processMultipleUsers(userIds: string[]): Promise<UserData[]> {
    const promises = userIds.map(id => processUser(id));
    
    try {
        // Concurrent execution
        const results = await Promise.all(promises);
        return results;
    } catch (error) {
        // Fallback to Promise.allSettled
        const settledResults = await Promise.allSettled(promises);
        return settledResults
            .filter(result => result.status === 'fulfilled')
            .map(result => (result as PromiseFulfilledResult<UserData>).value);
    }
}

// Dynamic import
async function loadModule(moduleName: string) {
    try {
        const module = await import(moduleName);
        return module;
    } catch (error) {
        console.error(`Failed to load module: ${moduleName}`, error);
    }
}

// Computed property access
function accessProperty(obj: any, propName: string) {
    return obj[propName];
}

// Callback pattern
function processWithCallback(data: any, callback: (error: Error | null, result?: any) => void) {
    setTimeout(() => {
        try {
            const result = data * 2;
            callback(null, result);
        } catch (error) {
            callback(error as Error);
        }
    }, 100);
}

// Event handlers
function setupEventHandlers(emitter: EventEmitter) {
    emitter.on('data', (data) => {
        console.log('Received data:', data);
    });
    
    emitter.addEventListener('error', (error) => {
        console.error('Error occurred:', error);
    });
}

// Utility types usage
type PartialConfig = Partial<Config>;
type RequiredConfig = Required<Config>;
type ConfigKeys = keyof Config;

// Conditional types
type NonNullable<T> = T extends null | undefined ? never : T;

// Main function (entry point)
export default async function main(): Promise<void> {
    const config: Config = {
        apiUrl: 'https://api.example.com',
        timeout: 10000,
        retries: 3
    };

    const client = new ApiClient<UserData>(config);
    
    try {
        await processUser('123');
        const users = await processMultipleUsers(['1', '2', '3']);
        console.log('Processed users:', users.length);
        
        // Dynamic module loading
        const module = await loadModule('./helpers');
        if (module) {
            console.log('Module loaded successfully');
        }
        
    } catch (error) {
        console.error('Main execution failed:', error);
        process.exit(1);
    }
}

// Export individual functions
export { processUser, validateInput, ApiClient, Priority };